"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useFieldFetchData = exports.proFieldParsingValueEnumToArray = exports.proFieldParsingText = exports.default = exports.ObjToMap = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _jsxRuntime = require("react/jsx-runtime");

var _proProvider = require("@ant-design/pro-provider");

var _proUtils = require("@ant-design/pro-utils");

var _antdV = require("antd-v4");

var _react = _interopRequireWildcard(require("react"));

var _swr = _interopRequireDefault(require("swr"));

var _Status = _interopRequireWildcard(require("../Status"));

require("./index.less");

var _LightSelect = _interopRequireDefault(require("./LightSelect"));

var _SearchSelect = _interopRequireDefault(require("./SearchSelect"));

var _excluded = ["value", "text"],
    _excluded2 = ["mode", "valueEnum", "render", "renderFormItem", "request", "fieldProps", "plain", "children", "light", "proFieldKey", "params", "label", "bordered", "id", "lightLabel", "labelTrigger"];

var ObjToMap = function ObjToMap(value) {
  if (getType(value) === 'map') {
    return value;
  }

  return new Map(Object.entries(value || {}));
};
/**
 * 转化 text 和 valueEnum 通过 type 来添加 Status
 *
 * @param text
 * @param valueEnum
 * @param pure 纯净模式，不增加 status
 */


exports.ObjToMap = ObjToMap;

var proFieldParsingText = function proFieldParsingText(text, valueEnumParams) {
  if (Array.isArray(text)) {
    return (0, _jsxRuntime.jsx)(_antdV.Space, {
      split: ",",
      size: 2,
      children: text.map(function (value) {
        return (// @ts-ignore
          proFieldParsingText(value, valueEnumParams)
        );
      })
    });
  }

  var valueEnum = ObjToMap(valueEnumParams);

  if (!valueEnum.has(text) && !valueEnum.has("".concat(text))) {
    // @ts-ignore
    return (text === null || text === void 0 ? void 0 : text.label) || text;
  }

  var domText = valueEnum.get(text) || valueEnum.get("".concat(text));

  if (!domText) {
    // @ts-ignore
    return (text === null || text === void 0 ? void 0 : text.label) || text;
  }

  var status = domText.status,
      color = domText.color;
  var Status = _Status.default[status || 'Init']; // 如果类型存在优先使用类型

  if (Status) {
    return (0, _jsxRuntime.jsx)(Status, {
      children: domText.text
    });
  } // 如果不存在使用颜色


  if (color) {
    return (0, _jsxRuntime.jsx)(_Status.ProFieldBadgeColor, {
      color: color,
      children: domText.text
    });
  } // 什么都没有使用 text


  return domText.text || domText;
};

exports.proFieldParsingText = proFieldParsingText;

var Highlight = function Highlight(_ref) {
  var label = _ref.label,
      words = _ref.words;

  var _useContext = (0, _react.useContext)(_antdV.ConfigProvider.ConfigContext),
      getPrefixCls = _useContext.getPrefixCls;

  var lightCls = getPrefixCls('pro-select-item-option-content-light');
  var optionCls = getPrefixCls('pro-select-item-option-content');
  var matchKeywordsRE = new RegExp(words.map(function (word) {
    return word.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
  }).join('|'), 'gi');
  var matchText = label;
  var elements = [];

  while (matchText.length) {
    var match = matchKeywordsRE.exec(matchText);

    if (!match) {
      elements.push(matchText);
      break;
    }

    var start = match.index;
    var matchLength = match[0].length + start;
    elements.push(matchText.slice(0, start), /*#__PURE__*/_react.default.createElement('span', {
      className: lightCls
    }, matchText.slice(start, matchLength)));
    matchText = matchText.slice(matchLength);
  }

  return /*#__PURE__*/_react.default.createElement.apply(_react.default, ['div', {
    className: optionCls
  }].concat(elements));
};
/**
 * 获取类型的 type
 *
 * @param obj
 */


function getType(obj) {
  // @ts-ignore
  var type = Object.prototype.toString.call(obj).match(/^\[object (.*)\]$/)[1].toLowerCase();
  if (type === 'string' && (0, _typeof2.default)(obj) === 'object') return 'object'; // Let "new String('')" return 'object'

  if (obj === null) return 'null'; // PhantomJS has type "DOMWindow" for null

  if (obj === undefined) return 'undefined'; // PhantomJS has type "DOMWindow" for undefined

  return type;
}
/**
 * 递归筛选 item
 *
 * @param item
 * @param keyWords
 * @returns
 */


function filerByItem(item, keyWords) {
  var _item$label, _item$value;

  if (!keyWords) return true;

  if ((item === null || item === void 0 ? void 0 : (_item$label = item.label) === null || _item$label === void 0 ? void 0 : _item$label.toString().toLowerCase().includes(keyWords.toLowerCase())) || (item === null || item === void 0 ? void 0 : (_item$value = item.value) === null || _item$value === void 0 ? void 0 : _item$value.toString().toLowerCase().includes(keyWords.toLowerCase()))) {
    return true;
  }

  if (item.optionType === 'optGroup' && (item.children || item.options)) {
    var findItem = [].concat((0, _toConsumableArray2.default)(item.children || []), [item.options || []]).find(function (mapItem) {
      return filerByItem(mapItem, keyWords);
    });
    if (findItem) return true;
  }

  return false;
}
/**
 * 把 value 的枚举转化为数组
 *
 * @param valueEnum
 */


var proFieldParsingValueEnumToArray = function proFieldParsingValueEnumToArray(valueEnumParams) {
  var enumArray = [];
  var valueEnum = ObjToMap(valueEnumParams);
  valueEnum.forEach(function (_, key) {
    var value = valueEnum.get(key) || valueEnum.get("".concat(key));

    if (!value) {
      return;
    }

    if ((0, _typeof2.default)(value) === 'object' && (value === null || value === void 0 ? void 0 : value.text)) {
      enumArray.push({
        text: value === null || value === void 0 ? void 0 : value.text,
        value: key,
        label: value === null || value === void 0 ? void 0 : value.text,
        disabled: value.disabled
      });
      return;
    }

    enumArray.push({
      text: value,
      value: key
    });
  });
  return enumArray;
};

exports.proFieldParsingValueEnumToArray = proFieldParsingValueEnumToArray;

var useFieldFetchData = function useFieldFetchData(props) {
  var _props$fieldProps, _props$fieldProps2, _ref3, _props$debounceTime, _props$fieldProps5, _props$fieldProps8;

  var cacheForSwr = props.cacheForSwr;

  var _useState = (0, _react.useState)(props.defaultKeyWords),
      _useState2 = (0, _slicedToArray2.default)(_useState, 2),
      keyWords = _useState2[0],
      setKeyWords = _useState2[1];
  /** Key 是用来缓存请求的，如果不在是有问题 */


  var _useState3 = (0, _react.useState)(function () {
    if (props.proFieldKey) {
      return props.proFieldKey.toString();
    }

    if (props.request) {
      return (0, _proUtils.nanoid)();
    }

    return 'no-fetch';
  }),
      _useState4 = (0, _slicedToArray2.default)(_useState3, 1),
      cacheKey = _useState4[0];

  var proFieldKeyRef = (0, _react.useRef)(cacheKey);
  var getOptionsFormValueEnum = (0, _react.useCallback)(function (coverValueEnum) {
    return proFieldParsingValueEnumToArray(ObjToMap(coverValueEnum)).map(function (_ref2) {
      var value = _ref2.value,
          text = _ref2.text,
          rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded);
      return (0, _objectSpread2.default)({
        label: text,
        value: value,
        key: value
      }, rest);
    });
  }, []);

  var _useMountMergeState = (0, _proUtils.useMountMergeState)(function () {
    if (props.valueEnum) {
      return getOptionsFormValueEnum(props.valueEnum);
    }

    return [];
  }, {
    value: ((_props$fieldProps = props.fieldProps) === null || _props$fieldProps === void 0 ? void 0 : _props$fieldProps.options) || ((_props$fieldProps2 = props.fieldProps) === null || _props$fieldProps2 === void 0 ? void 0 : _props$fieldProps2.treeData)
  }),
      _useMountMergeState2 = (0, _slicedToArray2.default)(_useMountMergeState, 2),
      options = _useMountMergeState2[0],
      setOptions = _useMountMergeState2[1];

  (0, _proUtils.useDeepCompareEffect)(function () {
    var _props$fieldProps3, _props$fieldProps4;

    // 优先使用 fieldProps?.options
    if (!props.valueEnum || ((_props$fieldProps3 = props.fieldProps) === null || _props$fieldProps3 === void 0 ? void 0 : _props$fieldProps3.options) || ((_props$fieldProps4 = props.fieldProps) === null || _props$fieldProps4 === void 0 ? void 0 : _props$fieldProps4.treeData)) return;
    setOptions(getOptionsFormValueEnum(props.valueEnum));
  }, [props.valueEnum]);
  var swrKey = (0, _proUtils.useDebounceValue)([proFieldKeyRef.current, props.params, keyWords], (_ref3 = (_props$debounceTime = props.debounceTime) !== null && _props$debounceTime !== void 0 ? _props$debounceTime : props === null || props === void 0 ? void 0 : (_props$fieldProps5 = props.fieldProps) === null || _props$fieldProps5 === void 0 ? void 0 : _props$fieldProps5.debounceTime) !== null && _ref3 !== void 0 ? _ref3 : 0, [props.params, keyWords]);

  var _useSWR = (0, _swr.default)(function () {
    if (!props.request) {
      return null;
    }

    return swrKey;
  }, function (_, params, kw) {
    return props.request((0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
      keyWords: kw
    }), props);
  }, {
    revalidateIfStale: !cacheForSwr,
    // 打开 cacheForSwr 的时候才应该支持两个功能
    revalidateOnReconnect: cacheForSwr,
    shouldRetryOnError: false,
    // @todo 这个功能感觉应该搞个API出来
    revalidateOnFocus: false
  }),
      data = _useSWR.data,
      setLocaleData = _useSWR.mutate,
      isValidating = _useSWR.isValidating;

  var resOptions = (0, _react.useMemo)(function () {
    var _props$fieldProps6, _props$fieldProps7;

    var opt = options === null || options === void 0 ? void 0 : options.map(function (item) {
      if (typeof item === 'string') {
        return {
          label: item,
          value: item
        };
      }

      if ((item === null || item === void 0 ? void 0 : item.optionType) === 'optGroup' && (item.children || item.options)) {
        var childrenOptions = [].concat((0, _toConsumableArray2.default)(item.children || []), (0, _toConsumableArray2.default)(item.options || [])).filter(function (mapItem) {
          return filerByItem(mapItem, keyWords);
        });
        return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, {
          children: childrenOptions,
          options: childrenOptions
        });
      }

      return item;
    }); // filterOption 为 true 时 filter数据, filterOption 默认为true

    if (((_props$fieldProps6 = props.fieldProps) === null || _props$fieldProps6 === void 0 ? void 0 : _props$fieldProps6.filterOption) === true || ((_props$fieldProps7 = props.fieldProps) === null || _props$fieldProps7 === void 0 ? void 0 : _props$fieldProps7.filterOption) === undefined) {
      return opt === null || opt === void 0 ? void 0 : opt.filter(function (item) {
        if (!item) return false;
        if (!keyWords) return true;
        return filerByItem(item, keyWords);
      });
    }

    return opt;
  }, [options, keyWords, (_props$fieldProps8 = props.fieldProps) === null || _props$fieldProps8 === void 0 ? void 0 : _props$fieldProps8.filterOption]);
  return [isValidating, props.request ? data : resOptions, function (fetchKeyWords) {
    setKeyWords(fetchKeyWords);
  }, function () {
    setKeyWords(undefined);
    setLocaleData([], false);
  }];
};
/**
 * 可以根据 valueEnum 来进行类型的设置
 *
 * @param
 */


exports.useFieldFetchData = useFieldFetchData;

var FieldSelect = function FieldSelect(props, ref) {
  var mode = props.mode,
      valueEnum = props.valueEnum,
      render = props.render,
      renderFormItem = props.renderFormItem,
      request = props.request,
      fieldProps = props.fieldProps,
      plain = props.plain,
      children = props.children,
      light = props.light,
      proFieldKey = props.proFieldKey,
      params = props.params,
      label = props.label,
      bordered = props.bordered,
      id = props.id,
      lightLabel = props.lightLabel,
      labelTrigger = props.labelTrigger,
      rest = (0, _objectWithoutProperties2.default)(props, _excluded2);
  var inputRef = (0, _react.useRef)();
  var intl = (0, _proProvider.useIntl)();
  var keyWordsRef = (0, _react.useRef)('');
  var fieldNames = fieldProps.fieldNames;
  (0, _react.useEffect)(function () {
    keyWordsRef.current = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.searchValue;
  }, [fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.searchValue]);

  var _useFieldFetchData = useFieldFetchData(props),
      _useFieldFetchData2 = (0, _slicedToArray2.default)(_useFieldFetchData, 4),
      loading = _useFieldFetchData2[0],
      options = _useFieldFetchData2[1],
      _fetchData = _useFieldFetchData2[2],
      resetData = _useFieldFetchData2[3];

  var size = (0, _react.useContext)(_antdV.ConfigProvider.SizeContext);
  (0, _react.useImperativeHandle)(ref, function () {
    return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, inputRef.current || {}), {}, {
      fetchData: function fetchData() {
        return _fetchData();
      }
    });
  });
  var optionsValueEnum = (0, _react.useMemo)(function () {
    if (mode !== 'read') return;

    var _ref4 = fieldNames || {},
        _ref4$label = _ref4.label,
        labelPropsName = _ref4$label === void 0 ? 'label' : _ref4$label,
        _ref4$value = _ref4.value,
        valuePropsName = _ref4$value === void 0 ? 'value' : _ref4$value,
        _ref4$options = _ref4.options,
        optionsPropsName = _ref4$options === void 0 ? 'options' : _ref4$options;

    var valuesMap = new Map();

    var traverseOptions = function traverseOptions(_options) {
      if (!(_options === null || _options === void 0 ? void 0 : _options.length)) {
        return valuesMap;
      }

      var length = _options.length;
      var i = 0;

      while (i < length) {
        var cur = _options[i++];
        valuesMap.set(cur[valuePropsName], cur[labelPropsName]);
        traverseOptions(cur[optionsPropsName]);
      }

      return valuesMap;
    };

    return traverseOptions(options);
  }, [fieldNames, mode, options]);

  if (mode === 'read') {
    var dom = (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
      children: proFieldParsingText(rest.text, ObjToMap(valueEnum || optionsValueEnum))
    });

    if (render) {
      return render(rest.text, (0, _objectSpread2.default)({
        mode: mode
      }, fieldProps), dom) || null;
    }

    return dom;
  }

  if (mode === 'edit' || mode === 'update') {
    var renderDom = function renderDom() {
      if (light) {
        return (0, _jsxRuntime.jsx)(_LightSelect.default, (0, _objectSpread2.default)({
          bordered: bordered,
          id: id,
          loading: loading,
          ref: inputRef,
          allowClear: true,
          size: size,
          options: options,
          label: label,
          placeholder: intl.getMessage('tableForm.selectPlaceholder', '请选择'),
          lightLabel: lightLabel,
          labelTrigger: labelTrigger
        }, fieldProps));
      }

      return (0, _jsxRuntime.jsx)(_SearchSelect.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({
        className: rest.className,
        style: (0, _objectSpread2.default)({
          minWidth: 100
        }, rest.style),
        bordered: bordered,
        id: id,
        loading: loading,
        ref: inputRef,
        allowClear: true,
        notFoundContent: loading ? (0, _jsxRuntime.jsx)(_antdV.Spin, {
          size: "small"
        }) : fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.notFoundContent,
        fetchData: function fetchData(keyWord) {
          keyWordsRef.current = keyWord;

          _fetchData(keyWord);
        },
        resetData: resetData,
        optionItemRender: function optionItemRender(item) {
          if (typeof item.label === 'string' && keyWordsRef.current) {
            return (0, _jsxRuntime.jsx)(Highlight, {
              label: item.label,
              words: [keyWordsRef.current]
            });
          }

          return item.label;
        },
        placeholder: intl.getMessage('tableForm.selectPlaceholder', '请选择'),
        label: label
      }, fieldProps), {}, {
        options: options
      }), "SearchSelect");
    };

    var _dom = renderDom();

    if (renderFormItem) {
      return renderFormItem(rest.text, (0, _objectSpread2.default)((0, _objectSpread2.default)({
        mode: mode
      }, fieldProps), {}, {
        options: options
      }), _dom) || null;
    }

    return _dom;
  }

  return null;
};

var _default = /*#__PURE__*/_react.default.forwardRef(FieldSelect);

exports.default = _default;